import 'package:flutter/material.dart';

class CPieChart extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return CPieChartState();
  }
}

class CPieChartState extends State<CPieChart>
    with SingleTickerProviderStateMixin {
  List<CPieChartEntiy> _items = List();
  double _total = 0;
  //构造数据
  void initData() {
    _items.clear();
    _total = 0;
    CPieChartEntiy chartEntiy1 =
        CPieChartEntiy('收入', 10, Colors.red, unititem: '元');
    CPieChartEntiy chartEntiy2 =
        CPieChartEntiy('支持', 30, Colors.green, unititem: '元');
    CPieChartEntiy chartEntiy3 =
        CPieChartEntiy('其他', 230, Colors.blue, unititem: '元');
    CPieChartEntiy chartEntiy4 =
        CPieChartEntiy('其他', 60, Colors.limeAccent, unititem: '元');
    CPieChartEntiy chartEntiy5 =
        CPieChartEntiy('其他', 630, Colors.greenAccent, unititem: '元');
    CPieChartEntiy chartEntiy6 =
        CPieChartEntiy('其他', 1230, Colors.pink, unititem: '元');
    CPieChartEntiy chartEntiy7 =
        CPieChartEntiy('其他', 160, Colors.purple, unititem: '元');
    CPieChartEntiy chartEntiy8 =
        CPieChartEntiy('其他', 640, Colors.orange, unititem: '元');
    _items.add(chartEntiy1);
    _items.add(chartEntiy2);
    _items.add(chartEntiy3);
    _items.add(chartEntiy4);
    _items.add(chartEntiy5);
    _items.add(chartEntiy6);
    _items.add(chartEntiy7);
    _items.add(chartEntiy8);

    //从小到大排序
    //_items.sort((c1, c2) => c1.nubitem.compareTo(c2.nubitem));
    //从大到小排序
    //_items.sort((c1, c2) => c2.nubitem.compareTo(c1.nubitem));

    for (CPieChartEntiy entiy in _items) {
      _total += entiy.nubitem;
    }
  }

  @override
  void initState() {
    initData();
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      width: double.infinity,
      height: 200,
      child: CustomPaint(
        child: Container(
          alignment: Alignment.topRight,
          child: ListView.builder(
            itemBuilder: (context, index) {
              return Container(
                alignment: Alignment.center,
                padding: EdgeInsets.only(top: 10, right: 20),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Container(
                      width: 10,
                      height: 10,
                      color: _items[index].itemColor,
                    ),
                    Text(
                        '${_items[index].nubitem}${_items[index].unititem == null ? "" : _items[index].unititem}')
                  ],
                ),
              );
            },
            itemCount: _items.length,
          ),
        ),
        painter: CPieChartPainter(
          _items,
          _total,
          marginLeft: 20,
        ),
      ),
    );
  }
}

class CPieChartEntiy {
  String subitem; //子项
  int nubitem; //子项数值
  String unititem; //子项数值单位
  Color itemColor = Colors.black; //占比颜色

  CPieChartEntiy(this.subitem, this.nubitem, this.itemColor, {this.unititem});
}

class CPieChartPainter extends CustomPainter {
  double marginLeft;
  List<CPieChartEntiy> pieItem;
  Paint _paint = new Paint();
  double startAngle = 0;
  double total; //总和

  CPieChartPainter(this.pieItem, this.total, {this.marginLeft = 0});

  @override
  void paint(Canvas canvas, Size size) {
    double width = size.width;
    double height = size.height;
    double r = (width > height ? height : width) / 2;
    _paint
      ..color = Colors.blueAccent
      ..strokeCap = StrokeCap.round
      ..isAntiAlias = true
      ..strokeWidth = 5.0
      ..style = PaintingStyle.fill;
    Offset center = Offset(r + marginLeft, r);
    //大圆半径
    double outer_radius = r - 10;

    //求矩形面
    Rect outre_rect = Rect.fromCircle(center: center, radius: outer_radius);

    //循环画扇形
    if (pieItem.length > 0) {
      for (int i = 0; i < pieItem.length; i++) {
        CPieChartEntiy chartEntiy = pieItem[i];

        customDraw(canvas, outre_rect, chartEntiy);
        if (i == pieItem.length) {
          startAngle = 0;
          total = 0;
        }
      }
    }
  }

  final pi = 3.1415926;

  //1°=π/180°，1rad=180°/π。
  //
  //一周是360度，也是2π弧度，即360°=2π.
  num degToRad(num deg) => deg * (pi / 180.0);

  num radToDeg(num rad) => rad * (180.0 / pi);

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }

  void customDraw(
    Canvas canvas,
    Rect outre_rect,
    CPieChartEntiy chartEntiy,
  ) {
    //第一个参数是矩形，第二个参数起始角度，第三个参数画多少个角度，第四个是画笔
    //一周360°
    double drawAngle = 360 / total * chartEntiy.nubitem;
    _paint.color = chartEntiy.itemColor;
    canvas.drawArc(
        outre_rect, degToRad(startAngle), degToRad(drawAngle), true, _paint);
    startAngle = startAngle + drawAngle;
  }
}
